Skip to content

OPENNLP-1866: Update Dev Manual on Unicode normalization and the UAX #29 tokenizer (4-docs/7) - #1106

Merged
mawiesne merged 13 commits into
mainfrom
OPENNLP-1850-4-docs
Jul 8, 2026
Merged

OPENNLP-1866: Update Dev Manual on Unicode normalization and the UAX #29 tokenizer (4-docs/7)#1106
mawiesne merged 13 commits into
mainfrom
OPENNLP-1850-4-docs

Conversation

@krickert

@krickert krickert commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Part 4-docs (7 of 7) of the OPENNLP-1850 stack: Developer Manual coverage of Unicode normalization and the UAX #29 tokenizer — a new "Text Normalization" chapter plus tokenizer / doccat / namefinder / introduction updates and the master opennlp.xml.

Base: OPENNLP-1850-3-dl (#1105).

@krickert

Copy link
Copy Markdown
Contributor Author

OPENNLP-1850 stacked PRs (review independently; merge bottom-up, re-targeting each base to main as the one below lands):

  1. OPENNLP-1850: Unicode normalization foundation — CharClass engine, rungs, Dimension (1/4) #1103 — Unicode normalization foundation (CharClass engine, rungs, Dimension)
  2. OPENNLP-1850: UAX #29 word tokenizer and the layered Term model (2/4) #1104 — UAX OPENNLP-910: Add checkstyle #29 word tokenizer + layered Term model
  3. OPENNLP-1865: Support offset-safe input normalization in the DL components (3-dl/7) #1105 — Offset-safe input normalization in the DL components
  4. OPENNLP-1866: Update Dev Manual on Unicode normalization and the UAX #29 tokenizer (4-docs/7) #1106 — Documentation

Supersedes #1101.

This comment was marked as outdated.

@krickert
krickert force-pushed the OPENNLP-1850-3-dl branch from 1c17110 to 8534bb3 Compare June 20, 2026 20:16
@krickert
krickert force-pushed the OPENNLP-1850-4-docs branch from 3037db7 to 9a71f28 Compare June 20, 2026 20:16
@rzo1

rzo1 commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Thx for the PR. Here are some suggestions:

  • Declare xmlns:xlink explicitly on the chapter roots of normalizer.xml and tokenizer.xml. Both use xlink:href (normalizer.xml:457, tokenizer.xml:461) but rely on the DocBook 5.0 DTD's #FIXED default to bind the prefix. The Maven build resolves the DTD so it works, but it breaks under any non-validating namespace-aware tool (IDE linters, xmllint --nonet), and every other chapter declares it explicitly:
    normalizer.xml: <chapter xml:id="tools.normalizer" xmlns:xlink="http://www.w3.org/1999/xlink">
    tokenizer.xml: <chapter xml:id="tools.tokenizer" xmlns:xlink="http://www.w3.org/1999/xlink">
    Note that tokenizer.xml newly introduces xlink usage, so this is the first chapter to add it there.

Otherwise the content is accurate.

@krickert
krickert force-pushed the OPENNLP-1850-3-dl branch from 8534bb3 to 5154da4 Compare June 21, 2026 19:00
@krickert
krickert force-pushed the OPENNLP-1850-4-docs branch 2 times, most recently from d7d316f to 0ff5d07 Compare June 21, 2026 19:21
@krickert
krickert force-pushed the OPENNLP-1850-3-dl branch from 5154da4 to c51f37d Compare June 21, 2026 19:21
@krickert
krickert force-pushed the OPENNLP-1850-4-docs branch 2 times, most recently from 667e850 to d71e472 Compare June 21, 2026 22:59
@krickert
krickert force-pushed the OPENNLP-1850-3-dl branch from 40698dc to 001ac01 Compare June 21, 2026 22:59
@krickert
krickert force-pushed the OPENNLP-1850-4-docs branch from b65c0de to 0022bc1 Compare June 22, 2026 00:19
@krickert
krickert force-pushed the OPENNLP-1850-3-dl branch 2 times, most recently from 038e23d to bc401d3 Compare June 22, 2026 01:52
@krickert
krickert force-pushed the OPENNLP-1850-4-docs branch from 0022bc1 to 2fd9543 Compare June 22, 2026 01:52
@krickert
krickert force-pushed the OPENNLP-1850-3-dl branch from bc401d3 to 4c12897 Compare June 22, 2026 02:10
@krickert
krickert force-pushed the OPENNLP-1850-4-docs branch from 2fd9543 to 743a955 Compare June 22, 2026 02:10
@krickert

Copy link
Copy Markdown
Contributor Author

Status since the last review. Normalizer chapter gains an "Offset-aware pipelines" section for buildAligned() and the capability interface with a worked dash-fold span example, the line-break-preserving rung in the fold table, and the supplementary-dash offset note in the DL fold options. Name-finder chapter names OffsetMappingNameFinder behind findInOriginal. docbkx HTML builds clean. Rebased onto the updated stack.

@rzo1

rzo1 commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Hi @krickert. I didn't have time to deeply review yet, so here you get some Fable 5 output. Take it with a grain of salt — I will read it next week myself (human in the loop).

The good news first: the model cross-checked the docs against the actual code on the branch and found the technical content fully accurate — all constructors/signatures in the samples exist as shown, all 12 xref targets resolve, XML is well-formed with the header matching the post-OPENNLP-1854 DTD convention, defaultChain() order matches the prose, and every expected-output comment ("cafe", the span arithmetic, 3.0 : NUMERIC, …) is pinned by an existing unit test. Everything below is clarity/duplication/structure, no factual errors.

Findings (most severe first):

  1. Duplication with drift (namefinder.xml, doccat.xml, normalizer.xml): the InferenceOptions folding + White_Space chunking story is told near-verbatim in three chapters, and the copies already disagree in wording ("folds each Unicode whitespace character" vs. "maps each Unicode whitespace code point" vs. "one code point to one space"). Suggestion: component chapters keep one sentence + the existing xref to tools.normalizer.dl as the single canonical explanation.

  2. tokenizer.xml intro: "The DL components apply that machinery automatically for document chunking" reads as if DL normalization is automatic, contradicting the "off by default" statements elsewhere — only chunking is automatic. The new paragraph also splits the intro sentence from the <screen> example it introduces. Suggested rewording: "The DL components perform Unicode-aware chunking automatically; the folding transforms remain opt-in."

  3. doccat.xml: the supplementary-plane dash / UTF-16 offset caveat is spelled out in full, but DocumentCategorizerDL exposes no span/offset API, so readers get surrogate-pair arithmetic they can never observe. One clause + xref would do.

  4. namefinder.xml: the second code sample repeats ~14 lines of the first (model, vocab, full 9-entry ids2Labels map, sentence detector) to add three InferenceOptions lines — and the copies already drift (different tokens arrays, different comments). Could be trimmed to just the options + constructor call.

  5. normalizer.xml: "rungs" is used as terminology three times but never introduced, while the same file also says "stage" for the same concept. Pick one (plain "stage" reads fine).

  6. namefinder.xml/doccat.xml: the offset-preservation sentence ("Whitespace folding is one code point to one character …, and so is dash folding for Basic Multilingual Plane dashes; a supplementary-plane dash shrinks from two UTF-16 units to one …") is a garden path with mixed units and unglossed jargon. Splitting into three short sentences (whitespace always safe → BMP dashes safe → rare non-BMP dashes shift, findInOriginal compensates) would fix it.

  7. normalizer.xml offset-aware section: two very dense sentences — the buildAligned() description with three nested "returns", and a ~63-word sentence ending "an offset that does not hold". Both accurate, both worth splitting.

  8. normalizer.xml intro: the "three principles" describe implementation strategy ("cursor-based, no regular expressions", "O(1)", "ReDoS"), and this internals-talk recurs ~8 more times across three chapters. The user-relevant contract is "Unicode-correct per the UCD, offset-preserving" — the no-regex/performance story could be stated once (or left to Javadoc) so the manual doesn't freeze internals as promises.

Minor: "lists the 25 characters carrying the White_Space property" will silently go stale on a UCD upgrade; the Catalan middle dot exemption in the bullet-normalizer table would benefit from the one-word reason (U+00B7 occurs inside Catalan words); "adding an unrequested dimension costs one transform" reads as a contradiction until you realize "adding" means "querying at runtime".

@krickert

krickert commented Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

@rzo1 addressed all the points in your claude. I'll have copilot do a round as well - cant hurt.

@jzonthemtn

Copy link
Copy Markdown
Contributor

Thanks for improving the docs.

@krickert

krickert commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for improving the docs.

Lots more coming.

@mawiesne

mawiesne commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Something looks weird here. There are commits + code changes in a PR that claims to provide the documentation. @krickert Can you verify the branch is up2date with main (-> rebase) and provide it in a clean fashion?

@krickert

krickert commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

On it let me reproduce it locally and take a look.. Should be pretty quick to do

@krickert

krickert commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

I had to rebase onto current main after #1105 merged. The branch is now 12 commits, 6 docbook files only (+778/−8). The earlier Java/DL noise was duplicate stack history. It should be gone after the reset/cherry-pick. Sorry about that, that one really did look weird.

@mawiesne mawiesne left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx @krickert and team. Please check my comments and quickly adjust the doc changes.

Comment thread opennlp-docs/src/docbkx/namefinder.xml Outdated
Comment thread opennlp-docs/src/docbkx/namefinder.xml Outdated
Comment thread opennlp-docs/src/docbkx/namefinder.xml
krickert added 13 commits July 8, 2026 10:14
…nd DL handling

Add the Text Normalization manual chapter (CharClass engine, normalizer pipeline, the Term
model, and the Aligned offset variants that return an AlignedText carrying an Alignment),
extend the tokenizer chapter with the UAX #29 segmenter, and document the DL components'
Unicode-aware chunking and opt-in whitespace/dash folding with offset-safe findInOriginal.
All embedded ONNX snippets are self-contained and compile.
…ligned)

Add an "Offset-aware pipelines" section to the normalizer chapter covering
TextNormalizer.Builder.buildAligned(), the OffsetAwareNormalizer capability
interface, mapping a match back to the source with AlignedText/Alignment, and the
fail-loud rejection of rungs that cannot report edits (NFC/NFKC). List the new
line-break-preserving whitespace rung in the normalizer family table.
… the manual

Document that NameFinderDL.findInOriginal comes from the OffsetMappingNameFinder
capability interface, detectable with a plain instanceof check, so the name-finder
chapter matches how the normalizer chapter presents OffsetAwareNormalizer.
…old options

Note in the normalizer manual that, with dash folding enabled, a dash in the
supplementary planes shrinks from two UTF-16 units to one and shifts later
offsets, so find reports offsets into the normalized text in that case while
findInOriginal maps them back to the original input. The one-for-one whitespace
fold versus the run-collapsing whitespace rung is already covered in the same
section.
Scope the "never relies on Character.isWhitespace" statement to the normalization
engine rather than the whole library. Note that getInstance() gives the default
shared instance and that case and accent folding also offer configured forms.
Refer to the conformance file by its full name WordBreakTest.txt.
…enizer manual

The Word Tokenizer section said it drops punctuation and keeps emoji without
noting that emoji means any Extended_Pictographic code point, so symbol-like
characters such as the copyright, trademark, and double-exclamation signs are
kept. Match the WordTokenizer class javadoc.
…d hyphenation

Show a concrete, exhaustive ids2Labels BIO mapping in the ONNX name-finder example instead of
an empty map (an unmapped predicted index raises IllegalStateException at runtime), and note the
exhaustiveness requirement. Hyphenate 'rule-based' and split the comma splice in the UAX #29
tokenizer section.
…ds2Labels example

Declare the xlink namespace on the normalizer and tokenizer chapter roots -- both use
<link xlink:href=...> (UAX #29 and UTS #39 references) but did not bind the prefix. Populate the
ids2Labels map in the second NameFinderDL example (the InferenceOptions/findInOriginal one), which
previously left it empty so the example would have located nothing.
…(); drop BM25/search framing

Update the Text Normalization chapter examples for the searchDefault()->defaultChain() and
searchAnalyzer()->matchingAnalyzer() renames, and drop the 'BM25-style search' phrasing.
…TD catalog form

main's OPENNLP-1854 switched every chapter to the local-catalog public id/URL (-//OASIS//DTD DocBook XML
5.0//EN, http://docbook.org/xml/5.0/dtd/docbook.dtd); the new normalizer chapter predated that, so align
it so the docs build resolves the DTD locally rather than over the network.
…tary-plane dashes

namefinder.xml and doccat.xml stated that whitespace and dash folding
both preserve character offsets. That is true for whitespace folding and
for Basic Multilingual Plane dashes, but a supplementary-plane dash
shrinks from two UTF-16 units to one and shifts later offsets, as the
InferenceOptions javadoc and the Text Normalization chapter already
document. Rewords both sentences to match and cross-references the
normalization chapter's DL section.
Use the UD English sentence model in the ONNX snippet and shorten the
InferenceOptions listing so it reuses the setup from the preceding example.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Pull requests that update documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants